package org.toycode.solr.extractor.impl;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.solr.common.SolrInputDocument;
import org.toycode.solr.config.Prop;
import org.toycode.solr.extractor.PropertyExtractor;

/**
 * This implementations of the interface {@linkplain PropertyExtractor}
 * provides the content extraction for the type <em>ms_excel</em> and
 * <em>ms_excels</em> in config.xml.
 *
 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
 * @version 1.0.0.1, Aug 26, 2009
 */
final public class MSExcelExtractor implements PropertyExtractor {

    private final List<String> EXTRACTABLE_TYPES = Arrays.asList("ms_excel",
                                                                 "ms_excels");

    @SuppressWarnings("unchecked")
    public void process(final Prop prop, final Object value,
                        final SolrInputDocument solrInputDocument) {
        final String type = prop.type;
        if (type.equals(EXTRACTABLE_TYPES.get(0))) {
            final String content = readExcel((String) value);
            solrInputDocument.addField("excel_content", content);
        } else if (type.equals(EXTRACTABLE_TYPES.get(0))) {
            final List<String> contents = new ArrayList<String>();
            for (final String path : ((Collection<String>) value)) {
                contents.add(readExcel(path));
            }
            solrInputDocument.addField("excel_content", contents);
        }
    }

    public List<String> getExtractableTypes() {
        return EXTRACTABLE_TYPES;
    }

    private static String readExcel(final String path) {
        try {
            final HSSFWorkbook workbook =
                    new HSSFWorkbook(new FileInputStream(path));
            final StringBuilder sb = new StringBuilder();
            for (int i = 0; i < workbook.getNumberOfSheets();
                 i++) {
                HSSFSheet childSheet = workbook.getSheetAt(i);
                for (int r = 0; r < childSheet.getPhysicalNumberOfRows();
                     r++) {
                    for (short c = 0;
                         c < childSheet.getRow(r).getPhysicalNumberOfCells();
                         c++) {
                        final HSSFCell cell = childSheet.getRow(r).getCell(c);
                        String value = null;
                        if (cell == null) {
                            continue;
                        }
                        switch (cell.getCellType()) {
                            case HSSFCell.CELL_TYPE_NUMERIC:
                                value = "" + cell.getNumericCellValue();
                                break;
                            case HSSFCell.CELL_TYPE_STRING:
                                value = cell.getStringCellValue();
                                break;
                            case HSSFCell.CELL_TYPE_BLANK:
                                continue;
                            default:
                        }
                        sb.append(value + " ");
                    }
                }
            }

            return sb.toString();
        } catch (final IOException ex) {
            Logger.getLogger(MSExcelExtractor.class.getName()).
                    log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public static void main(String[] args) {
        System.out.println(readExcel("src/test/resources/sample1.xls"));
    }
}
